package xmlrpc.client;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Vector;

import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;


/**
 * Implementation of the IServerCommunicator.
 * 	Also includes a ping method and a "getPlayerNumber" for syncronizing players in network play
 *  Holds an instance of XmlRpcClient.
 * 
 * @author nyblomv
 * 
 */
public class ServerCommunicator implements IServerCommunicator {
	// TODO Priority 2 put in xmlrpc constants
	private String localhost = "http://127.0.0.1:1337/xmlrpc";
	private XmlRpcClient client;
	private XmlRpcClientConfigImpl config= new XmlRpcClientConfigImpl();
	
	public ServerCommunicator() {

	}

	/**
	 * Initializes the client
	 */
	@Override
	public void initClient() throws MalformedURLException {
		client = new XmlRpcClient();
		// set necessary configs
		if (ClientUtil.getInstance().connectionOptions != null) {
			config.setServerURL(ClientUtil.getInstance().connectionOptions.getConnectionUrl());
		} else {
			config.setServerURL(new URL(localhost));
		}
		client.setConfig(config);
	}

	/**
	 * Simple ping method used for testing clients connection to server
	 * @return String "ping"
	 * @throws XmlRpcException
	 * @throws IOException
	 */
	@SuppressWarnings("unchecked")
	public String ping() throws XmlRpcException, IOException {
		initClient();
		System.out.println(client.execute("StringSender.getString", new Vector()));
		return "ping";

	}

	/**
	 * Method for getting a list of the latest non executed command strings.
	 * @param nr
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public ArrayList getCommandStringList(int nr){
		try {
			initClient();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		Object[] params = new Object[]{nr};
		try {
			return (ArrayList) client.execute("StringListSender", params);
		} catch (XmlRpcException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	@SuppressWarnings("unchecked")
	public String getCommandString(){
		try {
			initClient();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		try {
			return (String) client.execute("StringSender.getString", new Vector());
		} catch (XmlRpcException e) {
			e.printStackTrace();
		}
		return "fail";
	}
	@SuppressWarnings("unchecked")
	@Override
	public String sendCommandString(String s) throws XmlRpcException {
		
		Vector<String> params = new Vector<String>();
		params.addElement(s);
		try {
			initClient();
			client.execute("StringSender.setString", params);
			return (String) client.execute("StringSender.getString", new Vector());
		} catch (IOException e) {
			e.printStackTrace();
		}

		return "fail";
	}

	/**
	 * Method for acquiring the player number in network play. 
	 * @return id of the player. volatile so that it increases for each player.
	 */
	@SuppressWarnings("unchecked")
	public int getPlayerId(){
		int id=0;
		try {
			initClient();
			id = (Integer)client.execute("StringSender.getPlayerNumber", new Vector());
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (XmlRpcException e) {
			e.printStackTrace();
		}
		return id;
		
	}
}
